<?php
namespace Core\Service;
use Core\Object;
use Phalcon\Di\Injectable;
use Phalcon\Http\Request as PhalconRequest;

class Request extends Injectable
{
    public function register() {
        $this->di->setShared('request', new class extends PhalconRequest {

            protected $_params = [];

            protected function _merge($params) {
                if($body = $this->getHeader('RAW_BODY')) {
                    $body = json_decode(base64_decode($body), true);
                    if(is_array($body)) {
                        $aes = $this->getDI()->getCrypt()->aes;
                        if(isset($body['customer_id'])) {
                            $body['customer_id'] = $aes->decode($body['customer_id']);
                        }
                        $params = array_merge_recursive($params, $body);
                    }
                }
                return $params;
            }

            public function getParams() {
                if(!$this->_params) {
                    $get = $this->getQuery();
                    $post = $this->getPost();
                    $body = $this->getJsonRawBody(true) ?: [];
                    $this->_params = array_merge_recursive($get, $post, $body);
                    $this->_params = $this->_merge($this->_params);
                }
                return new Object($this->_params);
            }

            /**
             * @param array $params
             * @return $this
             */
            public function setParams(array $params) {
                foreach ($params as $key => $value) {
                    $this->setParam($key, $value);
                }
                return $this;
            }

            /**
             * Get an action parameter
             * @param $key
             * @param null $filters
             * @param null $defaultValue
             * @param bool $notAllowEmpty
             * @param bool $noRecursive
             * @return mixed
             * @internal param $name
             * @internal param string $key
             * @internal param mixed $default Default value to use if key not found
             */
            public function getParam($key, $filters = null, $defaultValue = null,
                                     $notAllowEmpty = false, $noRecursive = false) {
                $params = $this->getParams();
                $keys = preg_split ("/[.]+/", $key);
                foreach ($keys as $key) {
                    if(!$params->offsetExists($key)) {
                        break;
                    }
                    $params = $params->{$key};
                    if(!($params instanceof Object)) {
                        break;
                    }
                }
                if($params instanceof Object) {
                    return $params;
                }
                return $this->getHelper([$key => $params], $key, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
            }

            /**
             * Set an action parameter
             * A $value of null will unset the $key if it exists
             * @param string $key
             * @param mixed $value
             * @return Zend_Controller_Request_Abstract
             */
            public function setParam($key, $value) {
                $params = $this->getParams();
                $key = (string)$key;
                if ((null === $value) && isset($params[$key])) {
                    unset($params[$key]);
                } elseif (null !== $value) {
                    $params[$key] = $value;
                }
                $this->_params = $params;
                return $this;
            }

            /**
             * Unset all user parameters
             */
            public function clearParams() {
                $this->_params = [];
                return $this;
            }
        });
        return $this;
    }
}